#!/usr/bin/env python3
"""
虚拟信道提取诊断工具

用于诊断和验证特定文件的虚拟信道提取是否正确
可以帮助用户排查虚拟信道显示问题
"""

import sys
import os
import struct

# 添加项目根目录到Python路径
project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))
sys.path.insert(0, project_root)

from multi_format_frame_processor import MultiFormatFrameProcessor

def diagnose_file(file_path, frame_format):
    """诊断文件的虚拟信道提取"""
    print(f"\n{'='*60}")
    print(f"诊断文件: {file_path}")
    print(f"帧格式: {frame_format}字节")
    print(f"{'='*60}\n")
    
    if not os.path.exists(file_path):
        print(f"错误：文件不存在")
        return
    
    # 创建处理器
    processor = MultiFormatFrameProcessor()
    
    # 读取文件
    print("正在读取文件...")
    try:
        frames = processor.read_frames_with_format(file_path, frame_format)
        print(f"成功读取 {len(frames)} 帧\n")
    except Exception as e:
        print(f"读取失败: {str(e)}")
        return
    
    # 分析虚拟信道
    print("虚拟信道分析:")
    print("-" * 40)
    
    # 统计虚拟信道
    vc_count = {}
    for frame in frames:
        vc = frame.get('virtual_channel', 'N/A')
        vc_count[vc] = vc_count.get(vc, 0) + 1
    
    # 显示虚拟信道统计
    print(f"发现 {len(vc_count)} 个不同的虚拟信道:\n")
    for vc, count in sorted(vc_count.items()):
        percentage = (count / len(frames)) * 100
        print(f"  虚拟信道 {vc:2d}: {count:6d} 帧 ({percentage:6.2f}%)")
    
    # 显示前10帧的详细信息
    print("\n\n前10帧的详细信息:")
    print("-" * 60)
    print(f"{'帧号':^6} | {'帧计数':^12} | {'虚拟信道':^10} | {'同步字':^12}")
    print("-" * 60)
    
    for i, frame in enumerate(frames[:10]):
        frame_count = frame.get('frame_count', 0)
        vc = frame.get('virtual_channel', 'N/A')
        sync_word = frame.get('sync_word', 0)
        
        # 格式化帧计数为十六进制
        frame_count_hex = f"0x{frame_count:06X}"
        sync_word_hex = f"0x{sync_word:08X}"
        
        print(f"{i+1:^6} | {frame_count_hex:^12} | {vc:^10} | {sync_word_hex:^12}")
    
    # 验证虚拟信道提取的正确性
    print("\n\n虚拟信道提取验证:")
    print("-" * 40)
    
    # 检查第一帧的原始数据
    if frames and 'payload' in frames[0]:
        first_frame = frames[0]
        payload = first_frame['payload']
        
        if frame_format == '1092':
            # 1092格式：虚拟信道在第69字节（VCDU数据区第5字节）
            if len(payload) >= 6:
                # payload已经是从第64字节开始的VCDU数据
                vc_byte = payload[5]  # 第69字节
                vc_extracted = vc_byte & 0x3F
                print(f"第一帧原始数据验证:")
                print(f"  第69字节值: 0x{vc_byte:02X}")
                print(f"  提取的虚拟信道: {vc_extracted}")
                print(f"  帧中的虚拟信道: {first_frame['virtual_channel']}")
                print(f"  验证结果: {'✅ 正确' if vc_extracted == first_frame['virtual_channel'] else '❌ 错误'}")
        
        elif frame_format in ['1024', '896']:
            # 1024/896格式：虚拟信道在第5字节
            if len(payload) >= 6:
                vc_byte = payload[5]
                vc_extracted = vc_byte & 0x3F
                print(f"第一帧原始数据验证:")
                print(f"  第5字节值: 0x{vc_byte:02X}")
                print(f"  提取的虚拟信道: {vc_extracted}")
                print(f"  帧中的虚拟信道: {first_frame['virtual_channel']}")
                print(f"  验证结果: {'✅ 正确' if vc_extracted == first_frame['virtual_channel'] else '❌ 错误'}")
    
    # 检查是否有异常的虚拟信道值
    print("\n\n异常检查:")
    print("-" * 40)
    
    invalid_vcs = []
    for frame in frames:
        vc = frame.get('virtual_channel', -1)
        if vc < 0 or vc > 63:
            invalid_vcs.append((frames.index(frame), vc))
    
    if invalid_vcs:
        print(f"⚠️ 发现 {len(invalid_vcs)} 个异常的虚拟信道值:")
        for idx, vc in invalid_vcs[:10]:  # 只显示前10个
            print(f"  帧 {idx}: 虚拟信道 = {vc}")
    else:
        print("✅ 所有虚拟信道值都在有效范围内 (0-63)")
    
    # 检查空闲帧
    idle_count = vc_count.get(63, 0)
    if idle_count > 0:
        idle_percentage = (idle_count / len(frames)) * 100
        print(f"\n空闲帧统计: {idle_count} 帧 ({idle_percentage:.2f}%)")

def main():
    """主函数"""
    print("虚拟信道提取诊断工具")
    print("=" * 60)
    
    if len(sys.argv) < 3:
        print("\n使用方法:")
        print(f"  python {sys.argv[0]} <文件路径> <帧格式>")
        print("\n参数说明:")
        print("  文件路径: 要诊断的帧数据文件")
        print("  帧格式: 1092, 1024 或 896")
        print("\n示例:")
        print(f"  python {sys.argv[0]} data.dat 1092")
        print(f"  python {sys.argv[0]} frame_data.raw 1024")
        sys.exit(1)
    
    file_path = sys.argv[1]
    frame_format = sys.argv[2]
    
    # 验证帧格式
    if frame_format not in ['1092', '1024', '896']:
        print(f"\n错误：不支持的帧格式 '{frame_format}'")
        print("支持的格式: 1092, 1024, 896")
        sys.exit(1)
    
    # 执行诊断
    try:
        diagnose_file(file_path, frame_format)
    except Exception as e:
        print(f"\n诊断过程中发生错误: {str(e)}")
        import traceback
        traceback.print_exc()

if __name__ == "__main__":
    main() 